---
title: Generating Types from a GraphQL Schema
description: How to ensure your resolvers are type safe
---

> 👋 If you haven't set up a TypeScript project using Apollo Server yet, follow our [Getting Started](../getting-started) guide before continuing.

GraphQL uses a type system to clearly define the available data for each type and field in a [GraphQL schema](../schema/schema). Type generation libraries can take advantage of the strongly-typed nature of a GraphQL schema to automatically generate TypeScript types based on that schema.

You can use these generated TS types in your resolvers to type-check that your resolvers' return values match the field types dictated by your schema. Type checking your resolvers enables you to catch errors quickly and gives you the peace of mind that type safety ensures.

> Looking to generate types for your [Apollo Federation](/federation/) subgraphs? Our [Subgraph template](https://github.com/apollographql/subgraph-template-typescript-apollo-server) lays down the groundwork so you can quickly set up a subgraph with generated types.

## Setting up your project

We'll use the [GraphQL Code Generator](https://www.the-guild.dev/graphql/codegen) library to generate types based on our GraphQL schema. There are [multiple ways](https://www.the-guild.dev/graphql/codegen/plugins/typescript/typescript-resolvers#usage-example) to provide a schema to GraphQL Code Generator. Below, we'll show the most common method, which requires our schema to be in a `.graphql` file.

If you haven't already, move your server's schema into a `.graphql` file, like so:

```graphql title="schema.graphql"
type Query {
  books: [Book]
}

type Book {
  title: String
  author: String
}

type AddBookMutationResponse {
  code: String!
  success: Boolean!
  message: String!
  book: Book
}

type Mutation {
  addBook(title: String, author: String): AddBookMutationResponse
}
```

If you moved your schema into a `.graphql` file, update your imports to ensure you're still properly passing your schema to your server. In the file where you create your server, you can read in your schema using `readFileSync` from the `fs` package:

```ts title="src/index.ts"
// ...other imports
import { readFileSync } from 'fs';

// Note: this uses a path relative to the project's
// root directory, which is the current working directory
// if the server is executed using `npm run`.
const typeDefs = readFileSync('./schema.graphql', { encoding: 'utf-8' });

interface MyContext {
  dataSources: {
    books: Book[];
  };
}

const server = new ApolloServer<MyContext>({
  typeDefs,
  resolvers,
});

// ... start our server
```

Restart your server to ensure it can find and use your schema and that everything works as expected. Next, we'll install the packages we need to generate types automatically based on our schema.

### Installing and configuring dependencies

Run the following command to install the `@graphql-codegen/cli`, `@graphql-codegen/typescript`, and `@graphql-codegen/typescript-resolvers` packages into your project's dev dependencies:

```bash
npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers
```

> For more information on each package above, check out the [GraphQL Code Generator](https://www.the-guild.dev/graphql/codegen/plugins) docs.

Next, we'll set up a configuration file to tell GraphQL Code Generator where and how to generate types. You can do this by manually creating a `codegen.yml` file or by using the following command, which walks you through the process:

```bash
npx graphql-code-generator init
```

Below is an example of a `codegen.yml` file:

```yaml
# This configuration file tells GraphQL Code Generator how
# to generate types based on our schema.
schema: "./schema.graphql"
generates:
  # Specify where our generated types should live.
  ./src/__generated__/resolvers-types.ts:
    plugins:
      - "typescript"
      - "typescript-resolvers"
    config:
      useIndexSignature: true
      # More on this below!
      contextType: "../index#MyContext"
```

> [See the docs](https://www.the-guild.dev/graphql/codegen/plugins/typescript-resolvers#usage-example) for more information on the above configuration options.

Finally, we recommend adding helpful scripts to your `package.json` file to ensure your TS types are regularly generated:

```json
{
// ...
  "scripts": {
    "generate": "graphql-codegen --config codegen.yml",
    "compile": "npm run generate && tsc",
    "start": "npm run compile && node ./dist/index.js",
  },
// ...
}
```

> We also recommend [adding scripts to watch your code](https://github.com/apollographql/docs-examples/blob/main/apollo-server/v5/generated-types/package.json#L12), enabling your types to regenerate and your TypeScript files to recompile in the background as you work.

Above, running the `npm start` command generates types based on our GraphQL schema _and_ compiles our TypeScript code. The first time you run the `graphql-codegen` command, you'll see a file full of generated types at the path you specified in your `codegen.yml` file.

## Adding types to resolvers

The `typescript-resolvers` plugin creates a `Resolvers` type that you can use to add a type to your [resolver map](../data/resolvers#base-syntax), ensuring your resolvers return values match the field types specified by your schema.

Import the `Resolvers` type into the file where you define your resolvers:

```ts title="resolvers.ts"
// This is the file where our generated types live
// (specified in our `codegen.yml` file)
import { Resolvers } from './__generated__/resolvers-types';
```

You can now add the `Resolvers` type directly to your resolver map:

```ts
export const resolvers: Resolvers = {}
```

Your resolvers can now type check that the *arguments* and *return value* for each resolver match the schema:

```ts
export const resolvers: Resolvers = {
  Query: {
    // TypeScript now complains about the below resolver because
    // the data returned by this resolver doesn't match the schema type
    // (i.e., type Query { books: [Book] })
    books: () => {
      return "apple";
    },
  },
}
```

If your resolvers are in multiple files, you can pull out the corresponding generated types for the resolvers into those files. For example, below, we import the generated types into the separate files we have for our queries and mutations:

<CodeColumns>

```ts title="resolvers/queries.ts"
import { QueryResolvers } from '__generated__/resolvers-types';

// Use the generated `QueryResolvers`
// type to type check our queries!
const queries: QueryResolvers = {
  // ...queries
};

export default queries;
```

```ts title="resolvers/mutations.ts"
import { MutationResolvers } from '__generated__/resolvers-types';

// Use the generated `MutationResolvers` type
// to type check our mutations!
const mutations: MutationResolvers = {
  // ...mutations
};

export default mutations;
```

</CodeColumns>

### Context typing for resolvers

You can also configure GraphQL Code Generator to add a type for the context your resolvers share, ensuring TypeScript warns you if you attempt to use a value that doesn't exist.

To do this, you must first export the interface you pass to Apollo Server as a generic type parameter for typing your context value:

```ts title="src/index.ts"
// highlight-start
export interface MyContext {
  dataSources: {
    books: Book[];
  };
}
// highlight-end

const server = new ApolloServer<MyContext>({
  typeDefs,
  resolvers,
});
```

Remember the `contextType` from our [`codegen.yml` file above](#installing-and-configuring-dependencies)? You can pass your exported context interface to the `contextType` configuration option, like so:

```yaml
# ...
config:
  useIndexSignature: true
  # Providing our context's interface ensures our
  # context's type is set for all of our resolvers.

  # Note, this file path starts from the location of the
  # file where you generate types.
  # (i.e., `/src/__generated__/resolvers-types.ts` above)
  contextType: "../index#MyContext" # highlight-line
```

Once you regenerate your types, your context value is now automatically typed in all of your resolvers:

```ts
const resolvers: Resolvers = {
  Query: {
    // Our third argument (`contextValue`) has a type here, so we
    // can check the properties within our resolver's shared context value.
    books: (_, __, contextValue) => {
      return contextValue.dataSources.books;
    },
  },
}
```

## Basic runnable example

Check out our example using Apollo Server with generated types on CodeSandbox:

<ButtonLink
  href="https://codesandbox.io/s/github/apollographql/docs-examples/tree/main/apollo-server/v5/generated-types?fontsize=14&hidenavigation=1&initialpath=%2Fgraphql&theme=dark"
  size="lg"
>
  Edit in CodeSandbox
</ButtonLink>

See [GraphQL Code Generator's docs](https://www.the-guild.dev/graphql/codegen/docs/guides/further-reading) for further guidance on the different features and integrations it supports.
